package vip.xiaonuo.h5.royalty.modular.home.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.ObjUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import vip.xiaonuo.h5.royalty.modular.home.param.HomeSummaryParam;
import vip.xiaonuo.h5.royalty.modular.home.param.BusinessCalendarParam;
import vip.xiaonuo.h5.royalty.modular.home.param.IncomeTrendParam;
import vip.xiaonuo.h5.royalty.modular.home.vo.HomeSummaryVo;
import vip.xiaonuo.h5.royalty.modular.home.vo.BusinessCalendarPage;
import vip.xiaonuo.h5.royalty.modular.home.vo.BusinessCalendarVo;
import vip.xiaonuo.h5.royalty.modular.home.vo.IncomeTrendPage;
import vip.xiaonuo.h5.royalty.modular.home.vo.IncomeTrendVo;
import vip.xiaonuo.h5.royalty.modular.home.service.HomeService;
import vip.xiaonuo.h5.royalty.system.profitsharestatistics.entity.H5ProfitShareStatistics;
import vip.xiaonuo.h5.royalty.system.profitsharestatistics.service.H5ProfitShareStatisticsService;
import vip.xiaonuo.h5.royalty.system.profitsharerelation.service.H5ProfitShareRelationService;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 首页服务实现类
 */
@Service
public class HomeServiceImpl implements HomeService {
    @Autowired
    H5ProfitShareStatisticsService h5ProfitShareStatisticsService;

    @Autowired
    H5ProfitShareRelationService h5ProfitShareRelationService;

    @Override
    public HomeSummaryVo getSummary(HomeSummaryParam param) {
        String loginUserId = StpUtil.getLoginIdAsString();
        LambdaQueryWrapper<H5ProfitShareStatistics> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(H5ProfitShareStatistics::getSharePartyId, loginUserId);
        // 今日 昨日
        String queryDateStr = getQueryDateString(param.getDateType());
        queryWrapper.eq(H5ProfitShareStatistics::getStatisticsDate, queryDateStr);
        // 设置场站ID条件
        if (ObjUtil.isNotEmpty(param.getStationId())) {
            queryWrapper.eq(H5ProfitShareStatistics::getStationId, param.getStationId());
        }
        // 查询分润统计数据
        List<H5ProfitShareStatistics> statisticsList = h5ProfitShareStatisticsService.list(queryWrapper);

        // 计算汇总数据
        HomeSummaryVo homeSummaryVo = new HomeSummaryVo();
        if (statisticsList == null || statisticsList.isEmpty()) {
            homeSummaryVo.setActualFee(BigDecimal.ZERO.setScale(2, BigDecimal.ROUND_HALF_UP));
            homeSummaryVo.setServiceFee(BigDecimal.ZERO.setScale(2, BigDecimal.ROUND_HALF_UP));
            homeSummaryVo.setOtherFee(BigDecimal.ZERO.setScale(2, BigDecimal.ROUND_HALF_UP));
            homeSummaryVo.setOrders(0);
            homeSummaryVo.setShareRatio(new String[]{"0%"});
            return homeSummaryVo;
        }

        // 计算汇总值
        BigDecimal actualFee = BigDecimal.ZERO;
        BigDecimal serviceFee = BigDecimal.ZERO;
        BigDecimal otherFee = BigDecimal.ZERO;
        Integer orders = 0;
        // 使用HashSet存储唯一的分成比例值（字符串格式，带百分比）
        java.util.Set<String> uniqueShareRatios = new java.util.HashSet<>();

        for (H5ProfitShareStatistics stat : statisticsList) {
            BigDecimal statTotal = stat.getTotalShareAmount() != null ? stat.getTotalShareAmount() : BigDecimal.ZERO;
            actualFee = actualFee.add(statTotal);
            serviceFee = serviceFee.add(stat.getTotalServiceFee() != null ? stat.getTotalServiceFee() : BigDecimal.ZERO);
            otherFee = otherFee.add(BigDecimal.ZERO);
            orders += stat.getTotalOrderCount() != null ? stat.getTotalOrderCount() : 0;

            // 收集分成比例并转换为百分比字符串格式
            if (stat.getShareRatio() != null) {
                // 将BigDecimal转换为整数百分比字符串（例如：70 -> "70%"）
                uniqueShareRatios.add(stat.getShareRatio().intValue() + "%");
            }
        }

        // 设置保留两位小数的汇总数据
        homeSummaryVo.setActualFee(actualFee.setScale(2, BigDecimal.ROUND_HALF_UP));
        homeSummaryVo.setServiceFee(serviceFee.setScale(2, BigDecimal.ROUND_HALF_UP));
        homeSummaryVo.setOtherFee(otherFee.setScale(2, BigDecimal.ROUND_HALF_UP));
        homeSummaryVo.setOrders(orders);

        // 将唯一的分成比例转换为数组
        if (uniqueShareRatios.isEmpty()) {
            homeSummaryVo.setShareRatio(new String[]{"0%"});
        } else {
            homeSummaryVo.setShareRatio(uniqueShareRatios.toArray(new String[0]));
        }

        return homeSummaryVo;
    }

    @Override
    public BusinessCalendarPage getBusinessCalendar(BusinessCalendarParam param) {

        String loginUserId = StpUtil.getLoginIdAsString();

        // 构建查询条件
        LambdaQueryWrapper<H5ProfitShareStatistics> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(H5ProfitShareStatistics::getSharePartyId, loginUserId);

        // 设置月份条件 - 简化的日期范围查询
        int year = Integer.parseInt(param.getYear());
        int month = Integer.parseInt(param.getMonth());

        // 构造月份的第一天
        Calendar startCalendar = Calendar.getInstance();
        startCalendar.set(year, month - 1, 1);
        Date startDate = startCalendar.getTime();

        // 构造月份的最后一天
        Calendar endCalendar = Calendar.getInstance();
        endCalendar.set(year, month - 1, endCalendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        Date endDate = endCalendar.getTime();

        //查询当月所有数据
        queryWrapper.ge(H5ProfitShareStatistics::getStatisticsDate, startDate)
                .le(H5ProfitShareStatistics::getStatisticsDate, endDate);

        // 查询该月份的所有统计数据
        List<H5ProfitShareStatistics> statisticsList = h5ProfitShareStatisticsService.list(queryWrapper);

        // 步骤1：按日期分组，得到 Map<年月日, List<H5ProfitShareStatistics>>
        Map<String, List<H5ProfitShareStatistics>> dateGroupMap = statisticsList.stream()
                .collect(Collectors.groupingBy(stat -> {
                    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
                    return dateFormat.format(stat.getStatisticsDate());
                }));

        // 步骤2：每天的数据合并 得到Map<日,BusinessCalendarVo>
        Map<String, BusinessCalendarVo> dayDataMap = new HashMap<>();

        // 月总计收入
        BigDecimal monthTotalIncome = BigDecimal.ZERO;
        // 日均收入
        BigDecimal dayAvg = BigDecimal.ZERO;

        for (Map.Entry<String, List<H5ProfitShareStatistics>> entry : dateGroupMap.entrySet()) {
            String dateStr = entry.getKey();
            String dayStr = dateStr.substring(8); // 提取日号（格式：DD）
            List<H5ProfitShareStatistics> dayStats = entry.getValue();

            // 累加当天的所有站点数据
            BusinessCalendarVo dayData = new BusinessCalendarVo();
            dayData.setDay(dayStr);
            dayData.setHasData(true);

            // 判断是否为今天
            SimpleDateFormat currentDateFormat = new SimpleDateFormat("yyyy-MM-dd");
            String today = currentDateFormat.format(new Date());
            dayData.setIsToday(dateStr.equals(today));

            // 初始化默认值
            int totalOrders = 0;
            BigDecimal totalIncome = BigDecimal.ZERO;
            BigDecimal totalServiceFee = BigDecimal.ZERO;

            // 累加当天所有站点的数据
            for (H5ProfitShareStatistics stat : dayStats) {
                totalOrders += (stat.getTotalOrderCount() != null ? stat.getTotalOrderCount() : 0);
                totalIncome = totalIncome.add((stat.getTotalShareAmount() != null ? stat.getTotalShareAmount() : BigDecimal.ZERO));
                totalServiceFee = totalServiceFee.add((stat.getTotalServiceFee() != null ? stat.getTotalServiceFee() : BigDecimal.ZERO));
            }

            dayData.setOrders(totalOrders);
            dayData.setActualIncome(totalIncome.setScale(2, BigDecimal.ROUND_HALF_UP));
            dayData.setTotalServiceFee(totalServiceFee.setScale(2, BigDecimal.ROUND_HALF_UP));
            dayData.setOtherFee(BigDecimal.ZERO.setScale(2, BigDecimal.ROUND_HALF_UP));

            dayDataMap.put(dayStr, dayData); // 使用日号作为key

            // 统计月总计
            monthTotalIncome = monthTotalIncome.add(totalIncome);
        }

        // 步骤3：生成完整的日历数据列表（包括没有数据的日期）
        List<BusinessCalendarVo> calendarList = new ArrayList<>();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String todayStr = dateFormat.format(new Date());

        // 获取当月的天数
        int daysInMonth = endCalendar.getActualMaximum(Calendar.DAY_OF_MONTH);

        // 遍历当月所有日期
        for (int i = 1; i <= daysInMonth; i++) {
            String dayStr = String.format("%02d", i);

            BusinessCalendarVo dayVo = dayDataMap.get(dayStr);

            if (dayVo == null) {
                // 如果当天没有数据，创建空数据对象
                dayVo = new BusinessCalendarVo();
                dayVo.setDay(dayStr);
                dayVo.setHasData(false);

                // 判断是否为今天
                String currentDateStr = String.format("%04d-%02d-%02d", year, month, i);
                dayVo.setIsToday(currentDateStr.equals(todayStr));

                dayVo.setOrders(0);
                dayVo.setActualIncome(BigDecimal.ZERO.setScale(2, BigDecimal.ROUND_HALF_UP));
                dayVo.setTotalServiceFee(BigDecimal.ZERO.setScale(2, BigDecimal.ROUND_HALF_UP));
                dayVo.setOtherFee(BigDecimal.ZERO.setScale(2, BigDecimal.ROUND_HALF_UP));
            }

            calendarList.add(dayVo);
        }

        // 步骤4：创建并设置返回对象
        BusinessCalendarPage result = new BusinessCalendarPage();
        result.setYear(param.getYear());
        result.setMonth(param.getMonth());

        // 判断是否为当前月份
        Calendar currentCalendar = Calendar.getInstance();
        boolean isCurrentMonth = (currentCalendar.get(Calendar.YEAR) == year &&
                currentCalendar.get(Calendar.MONTH) + 1 == month);
        result.setIsCurrentMonth(isCurrentMonth);

        // 设置月总计收入（保留两位小数）
        result.setMonthTotal(monthTotalIncome.setScale(2, BigDecimal.ROUND_HALF_UP));

        // 计算并设置日均收入（保留两位小数，除以当月所有天数）
        dayAvg = monthTotalIncome.divide(BigDecimal.valueOf(daysInMonth), 2, BigDecimal.ROUND_HALF_UP);
        result.setDayAvg(dayAvg);

        // 设置日历数据列表
        result.setList(calendarList);

        return result;
    }

    @Override
    public IncomeTrendPage getIncomeTrend(IncomeTrendParam param) {
        String loginUserId = StpUtil.getLoginIdAsString();

        // 构建查询条件
        LambdaQueryWrapper<H5ProfitShareStatistics> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(H5ProfitShareStatistics::getSharePartyId, loginUserId);

        // 设置月份条件
        int year = Integer.parseInt(param.getYear());
        int month = Integer.parseInt(param.getMonth());

        // 构造月份的第一天和最后一天
        Calendar calendar = Calendar.getInstance();
        calendar.set(year, month - 1, 1);
        Date startDate = calendar.getTime();
        Date endDate = calendar.getTime();
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        endDate = calendar.getTime();

        // 查询当月所有数据
        queryWrapper.ge(H5ProfitShareStatistics::getStatisticsDate, startDate)
                .le(H5ProfitShareStatistics::getStatisticsDate, endDate);

        // 查询该月份的所有统计数据
        List<H5ProfitShareStatistics> statisticsList = h5ProfitShareStatisticsService.list(queryWrapper);

        // 按日期分组
        Map<String, List<H5ProfitShareStatistics>> dateGroupMap = statisticsList.stream()
                .collect(Collectors.groupingBy(stat -> {
                    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
                    return dateFormat.format(stat.getStatisticsDate());
                }));

        // 生成收入趋势数据列表
        List<IncomeTrendVo> trendList = new ArrayList<>();
        int daysInMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);

        // 遍历当月所有日期
        for (int i = 1; i <= daysInMonth; i++) {
            String dateStr = String.format("%04d-%02d-%02d", year, month, i);
            IncomeTrendVo trendVo = new IncomeTrendVo();
            trendVo.setDate(dateStr);

            List<H5ProfitShareStatistics> dayStats = dateGroupMap.get(dateStr);

            if (dayStats != null && !dayStats.isEmpty()) {
                // 累加当天所有站点的数据
                BigDecimal dayIncome = BigDecimal.ZERO;
                BigDecimal dayServiceFee = BigDecimal.ZERO;
                Integer dayOrders = 0;

                for (H5ProfitShareStatistics stat : dayStats) {
                    dayIncome = dayIncome.add(stat.getTotalShareAmount() != null ? stat.getTotalShareAmount() : BigDecimal.ZERO);
                    dayServiceFee = dayServiceFee.add(stat.getTotalServiceFee() != null ? stat.getTotalServiceFee() : BigDecimal.ZERO);
                    dayOrders += stat.getTotalOrderCount() != null ? stat.getTotalOrderCount() : 0;
                }

                trendVo.setActualIncome(dayIncome.setScale(2, BigDecimal.ROUND_HALF_UP));
                trendVo.setOrders(dayOrders);
                trendVo.setOtherFee(BigDecimal.ZERO.setScale(2, BigDecimal.ROUND_HALF_UP));
            } else {
                // 当天没有数据
                trendVo.setActualIncome(BigDecimal.ZERO.setScale(2, BigDecimal.ROUND_HALF_UP));
                trendVo.setOrders(0);
                trendVo.setOtherFee(BigDecimal.ZERO.setScale(2, BigDecimal.ROUND_HALF_UP));
            }

            trendList.add(trendVo);
        }

        // 创建并设置返回对象
        IncomeTrendPage result = new IncomeTrendPage();
        result.setYear(param.getYear());
        result.setMonth(param.getMonth());
        result.setList(trendList);

        return result;
    }

    /**
     * 根据日期类型获取查询日期字符串
     *
     * @param dateType 日期类型：0-昨天，1-今天
     * @return 查询日期字符串（格式：yyyy-MM-dd）
     */
    private String getQueryDateString(String dateType) {
        Calendar calendar = Calendar.getInstance();

        // 使用字典值判断：0=昨天，1=今天
        if ("0".equals(dateType)) {
            calendar.add(Calendar.DAY_OF_MONTH, -1);
        }
        // 1=今天：使用当前日期

        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH) + 1; // Calendar.MONTH从0开始
        int day = calendar.get(Calendar.DAY_OF_MONTH);

        // 格式化为yyyy-MM-dd
        return String.format("%d-%02d-%02d", year, month, day);
    }


}
